home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / misc / sci / ephem_src_4_28.lha / formats.c < prev    next >
C/C++ Source or Header  |  1992-05-24  |  8KB  |  401 lines

  1. /* basic formating routines.
  2.  * all the screen oriented printing should go through here.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <math.h>
  7. #include <ctype.h>
  8. #ifdef VMS
  9. #include <stdlib.h>
  10. #endif
  11. #include "astro.h"
  12. #include "screen.h"
  13.  
  14. extern char *strcpy();
  15.  
  16. /* suppress screen io if this is true, but always flog stuff.
  17.  */
  18. static int f_scrnoff;
  19. f_on ()
  20. {
  21.     f_scrnoff = 0;
  22. }
  23. f_off ()
  24. {
  25.     f_scrnoff = 1;
  26. }
  27.  
  28. /* draw n blanks at the given cursor position.  */
  29. f_blanks (r, c, n)
  30. int r, c, n;
  31. {
  32.     if (f_scrnoff)
  33.         return;
  34.     c_pos (r, c);
  35.     while (--n >= 0)
  36. #ifdef AMIGA
  37.         cputchar (' ');
  38. #else
  39.         putchar (' ');
  40. #endif
  41. }
  42.  
  43. /* print the given value, v, in "sexadecimal" format at [r,c]
  44.  * ie, in the form A:m.P, where A is a digits wide, P is p digits.
  45.  * if p == 0, then no decimal point either.
  46.  */
  47. f_sexad (r, c, a, p, mod, v)
  48. int r, c;
  49. int a, p;    /* left space, min precision */
  50. int mod;    /* don't let whole portion get this big */
  51. double v;
  52. {
  53.     char astr[32], str[32];
  54.     long dec;
  55.     double frac;
  56.     int visneg;
  57.     double vsav = v;
  58.  
  59.     if (v >= 0.0)
  60.         visneg = 0;
  61.     else {
  62.         if (v <= -0.5/60.0*pow(10.0,-1.0*p)) {
  63.         v = -v;
  64.         visneg = 1;
  65.         } else {
  66.         /* don't show as negative if less than the precision showing */
  67.         v = 0.0;
  68.         visneg = 0;
  69.         }
  70.     }
  71.  
  72.     dec = v;
  73.     frac = (v - dec)*60.0;
  74.     (void) sprintf (str, "59.%.*s5", p, "999999999");
  75.     if (frac >= atof (str)) {
  76.         dec += 1;
  77.         frac = 0.0;
  78.     }
  79.     dec %= mod;
  80.     if (dec == 0 && visneg)
  81.         (void) strcpy (str, "-0");
  82.     else
  83.         (void) sprintf (str, "%ld", visneg ? -dec : dec);
  84.  
  85.     /* would just do this if Turbo-C 2.0 %?.0f" worked:
  86.      * sprintf (astr, "%*s:%0*.*f", a, str, p == 0 ? 2 : p+3, p, frac);
  87.      */
  88.     if (p == 0)
  89.         (void) sprintf (astr, "%*s:%02d", a, str, (int)(frac+0.5));
  90.     else
  91.         (void) sprintf (astr, "%*s:%0*.*f", a, str, p+3, p, frac);
  92.  
  93.     (void) flog_log (r, c, vsav, astr);
  94.  
  95.     f_string (r, c, astr);
  96. }
  97.  
  98. /* print the given value, t, in sexagesimal format at [r,c]
  99.  * ie, in the form T:mm:ss, where T is nd digits wide.
  100.  * N.B. we assume nd >= 2.
  101.  */
  102. f_sexag (r, c, nd, t)
  103. int r, c, nd;
  104. double t;
  105. {
  106.     char tstr[32];
  107.     int h, m, s;
  108.     int tisneg;
  109.     
  110.     dec_sex (t, &h, &m, &s, &tisneg);
  111.     if (h == 0 && tisneg)
  112.         (void) sprintf (tstr, "%*s-0:%02d:%02d", nd-2, "", m, s);
  113.     else
  114.         (void) sprintf (tstr, "%*d:%02d:%02d", nd, tisneg ? -h : h, m, s);
  115.  
  116.     (void) flog_log (r, c, t, tstr);
  117.     f_string (r, c, tstr);
  118. }
  119.  
  120. /* print angle ra, in radians, in ra hours as hh:mm.m at [r,c]
  121.  * N.B. we assume ra is >= 0.
  122.  */
  123. f_ra (r, c, ra)
  124. int r, c;
  125. double ra;
  126. {
  127.     f_sexad (r, c, 2, 1, 24, radhr(ra));
  128. }
  129.  
  130. /* print time, t, as hh:mm:ss */
  131. f_time (r, c, t)
  132. int r, c;
  133. double t;
  134. {
  135.     f_sexag (r, c, 2, t);
  136. }
  137.  
  138. /* print time, t, as +/-hh:mm:ss (don't show leading +) */
  139. f_signtime (r, c, t)
  140. int r, c;
  141. double t;
  142. {
  143.     f_sexag (r, c, 3, t);
  144. }
  145.  
  146. /* print time, t, as hh:mm */
  147. f_mtime (r, c, t)
  148. int r, c;
  149. double t;
  150. {
  151.     f_sexad (r, c, 2, 0, 24, t);
  152. }
  153.  
  154. /* print angle, a, in rads, as degress at [r,c] in form ddd:mm */
  155. f_angle(r, c, a)
  156. int r, c;
  157. double a;
  158. {
  159.     f_sexad (r, c, 3, 0, 360, raddeg(a));
  160. }
  161.  
  162. /* print angle, a, in rads, as degress at [r,c] in form dddd:mm:ss */
  163. f_gangle(r, c, a)
  164. int r, c;
  165. double a;
  166. {
  167.     f_sexag (r, c, 4, raddeg(a));
  168. }
  169.  
  170. /* print the given modified Julian date, jd, as the starting date at [r,c]
  171.  * in the form mm/dd/yyyy.
  172.  */
  173. f_date (r, c, jd)
  174. int r, c;
  175. double jd;
  176. {
  177.     char dstr[32];
  178.     int m, y;
  179.     double d, tmp;
  180.  
  181.     mjd_cal (jd, &m, &d, &y);
  182.     (void) sprintf (dstr, "%2d/%02d/%-4d", m, (int)(d), y);
  183.  
  184.     /* shadow to the plot subsystem as years. */
  185.     mjd_year (jd, &tmp);
  186.     (void) flog_log (r, c, tmp, dstr);
  187.     f_string (r, c, dstr);
  188. }
  189.  
  190. /* print the given double as a rounded int, with the given format.
  191.  * this is used to plot full precision, but display far less.
  192.  * N.B. caller beware that we really do expect fmt to refer to an int, not
  193.  *   a long for example. also beware of range that implies.
  194.  */
  195. f_int (row, col, fmt, f)
  196. int row, col;
  197. char fmt[];
  198. double f;
  199. {
  200.     char str[80];
  201.     int i;
  202.  
  203.     i = (f < 0) ? (int)(f-0.5) : (int)(f+0.5);
  204.     (void) sprintf (str, fmt, i);
  205.  
  206.     (void) flog_log (row, col, f, str);
  207.     f_string (row, col, str);
  208. }
  209.  
  210. f_char (row, col, c)
  211. int row, col;
  212. char c;
  213. {
  214.     if (f_scrnoff)
  215.         return;
  216.     c_pos (row, col);
  217. #ifdef AMIGA
  218.     cputchar(c);
  219. #else
  220.     putchar (c);
  221. #endif
  222. }
  223.  
  224. f_string (r, c, s)
  225. int r, c;
  226. char *s;
  227. {
  228.     if (f_scrnoff)
  229.         return;
  230.     c_pos (r, c);
  231. #ifdef AMIGA
  232.     cwrite(s);
  233. #else
  234.     (void) fputs (s, stdout);
  235. #endif
  236. }
  237.  
  238. f_double (r, c, fmt, f)
  239. int r, c;
  240. char *fmt;
  241. double f;
  242. {
  243.     char str[80];
  244.     (void) sprintf (str, fmt, f);
  245.     (void) flog_log (r, c, f, str);
  246.     f_string (r, c, str);
  247. }
  248.  
  249. /* print prompt line */
  250. f_prompt (p)
  251. char *p;
  252. {
  253.     c_pos (R_PROMPT, C_PROMPT);
  254.     c_eol ();
  255.     c_pos (R_PROMPT, C_PROMPT);
  256. #ifdef AMIGA
  257.     cwrite(p);
  258. #else
  259.     (void) fputs (p, stdout);
  260. #endif
  261. }
  262.  
  263. /* clear from [r,c] to end of line, if we are drawing now. */
  264. f_eol (r, c)
  265. int r, c;
  266. {
  267.     if (!f_scrnoff) {
  268.         c_pos (r, c);
  269.         c_eol();
  270.     }
  271. }
  272.  
  273. /* print a message and wait for op to hit any key */
  274. f_msg (m)
  275. char *m;
  276. {
  277.     f_prompt (m);
  278.     (void) read_char();
  279. }
  280.  
  281. /* crack a line of the form X?X?X into its components,
  282.  *   where X is an integer and ? can be any character except '0-9' or '-',
  283.  *   such as ':' or '/'.
  284.  * only change those fields that are specified:
  285.  *   eg:  ::10    only changes *s
  286.  *        10    only changes *d
  287.  *        10:0  changes *d and *m
  288.  * if see '-' anywhere, first non-zero component will be made negative.
  289.  */
  290. f_sscansex (bp, d, m, s)
  291. char *bp;
  292. int *d, *m, *s;
  293. {
  294.     char c;
  295.     int *p = d;
  296.     int *nonzp = 0;
  297.     int sawneg = 0;
  298.     int innum = 0;
  299.  
  300.     while (c = *bp++)
  301.         if (isdigit(c)) {
  302.         if (!innum) {
  303.             *p = 0;
  304.             innum = 1;
  305.         }
  306.         *p = *p*10 + (c - '0');
  307.         if (*p && !nonzp)
  308.             nonzp = p;
  309.         } else if (c == '-') {
  310.         sawneg = 1;
  311.         } else if (c != ' ') {
  312.         /* advance to next component */
  313.         p = (p == d) ? m : s;
  314.         innum = 0;
  315.         }
  316.  
  317.     if (sawneg && nonzp)
  318.         *nonzp = -*nonzp;
  319. }
  320.  
  321. /* crack a floating date string, bp, of the form m/d/y, where d may be a
  322.  *   floating point number, into its components.
  323.  * leave any component unspecified unchanged.
  324.  * actually, the slashes may be anything but digits or a decimal point.
  325.  * this is functionally the same as f_sscansex() exept we allow for
  326.  *   the day portion to be real, and we don't handle negative numbers.
  327.  *   maybe someday we could make a combined one and use it everywhere.
  328.  */
  329. f_sscandate (bp, m, d, y)
  330. char *bp;
  331. int *m, *y;
  332. double *d;
  333. {
  334.     char *bp0, c;
  335.  
  336.     bp0 = bp;
  337.     while ((c = *bp++) && isdigit(c))
  338.         continue;
  339.     if (bp > bp0+1)
  340.         *m = atoi (bp0);
  341.     if (c == '\0')
  342.         return;
  343.     bp0 = bp;
  344.     while ((c = *bp++) && (isdigit(c) || c == '.'))
  345.         continue;
  346.     if (bp > bp0+1)
  347.         *d = atof (bp0);
  348.     if (c == '\0')
  349.         return;
  350.     bp0 = bp;
  351.     while (c = *bp++)
  352.         continue;
  353.     if (bp > bp0+1)
  354.         *y = atoi (bp0);
  355. }
  356.  
  357. /* just like dec_sex() but makes the first non-zero element negative if
  358.  * x is negative (instead of returning a sign flag).
  359.  */
  360. f_dec_sexsign (x, h, m, s)
  361. double x;
  362. int *h, *m, *s;
  363. {
  364.     int n;
  365.     dec_sex (x, h, m, s, &n);
  366.     if (n) {
  367.         if (*h)
  368.         *h = -*h;
  369.         else if (*m)
  370.         *m = -*m;
  371.         else
  372.         *s = -*s;
  373.     }
  374. }
  375.  
  376. /* return 1 if bp looks like a decimal year; else 0.
  377.  * any number greater than 12 or less than 0 is assumed to be a year, or any
  378.  * string with exactly one decimal point, an optional minus sign, and nothing
  379.  * else but digits.
  380.  */
  381. decimal_year (bp)
  382. char *bp;
  383. {
  384.     char c;
  385.     int ndig = 0, ndp = 0, nneg = 0, nchar = 0;
  386.     double y = atof(bp);
  387.  
  388.     while (c = *bp++) {
  389.         nchar++;
  390.         if (isdigit(c))
  391.         ndig++;
  392.         else if (c == '.')
  393.         ndp++;
  394.         else if (c == '-')
  395.         nneg++;
  396.     }
  397.  
  398.     return (y > 12 || y < 0
  399.             || (ndp == 1 && nneg <= 1 && nchar == ndig+ndp+nneg));
  400. }
  401.